// Copyright 2017 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_AVAIL_H_
#define CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_AVAIL_H_

#include <queue>
#include <set>

#include "core/fpdfapi/parser/cpdf_data_avail.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"

class CPDF_SyntaxParser;

class CPDF_CrossRefAvail {
 public:
  CPDF_CrossRefAvail(CPDF_SyntaxParser* parser,
                     FX_FILESIZE last_crossref_offset);
  ~CPDF_CrossRefAvail();

  FX_FILESIZE last_crossref_offset() const { return last_crossref_offset_; }

  CPDF_DataAvail::DocAvailStatus CheckAvail();

 private:
  enum class State {
    kCrossRefCheck,
    kCrossRefTableItemCheck,
    kCrossRefTableTrailerCheck,
    kDone,
  };

  bool CheckReadProblems();
  bool CheckCrossRef();
  bool CheckCrossRefTable();
  bool CheckCrossRefTableItem();
  bool CheckCrossRefTableTrailer();
  bool CheckCrossRefStream();

  void AddCrossRefForCheck(FX_FILESIZE crossref_offset);

  RetainPtr<CPDF_ReadValidator> GetValidator();

  UnownedPtr<CPDF_SyntaxParser> const parser_;
  const FX_FILESIZE last_crossref_offset_;
  CPDF_DataAvail::DocAvailStatus status_ = CPDF_DataAvail::kDataNotAvailable;
  State state_ = State::kCrossRefCheck;
  FX_FILESIZE offset_ = 0;
  std::queue<FX_FILESIZE> cross_refs_for_check_;
  std::set<FX_FILESIZE> registered_crossrefs_;
};

#endif  // CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_AVAIL_H_
 
以下是 `CPDF_CrossRefAvail` 类中提供的接口功能：

### 构造函数和析构函数
1. **CPDF_CrossRefAvail(CPDF_SyntaxParser* parser, FX_FILESIZE last_crossref_offset)**: 构造函数，初始化解析器和最后的交叉引用偏移量。
2. **~CPDF_CrossRefAvail()**: 析构函数，负责清理资源。

### 公共方法
3. **last_crossref_offset()**: 返回最后的交叉引用偏移量。
4. **CheckAvail()**: 检查交叉引用的可用性状态，返回 `CPDF_DataAvail::DocAvailStatus` 以指示状态。

### 私有方法
5. **CheckReadProblems()**: 检查读取过程中是否存在问题。
6. **CheckCrossRef()**: 检查交叉引用的状态。
7. **CheckCrossRefTable()**: 检查交叉引用表的状态。
8. **CheckCrossRefTableItem()**: 检查交叉引用表项目的状态。
9. **CheckCrossRefTableTrailer()**: 检查交叉引用表尾随信息的状态。
10. **CheckCrossRefStream()**: 检查交叉引用流的状态。

### 助手功能
11. **AddCrossRefForCheck(FX_FILESIZE crossref_offset)**: 将交叉引用偏移量添加到检查队列。
12. **GetValidator()**: 获取读取验证器（`RetainPtr<CPDF_ReadValidator>`）。

### 数据成员
- 枚举类型 **State**: 枚举交叉引用检查的不同状态。
- 成员变量包括：
  - **parser_**: `UnownedPtr<CPDF_SyntaxParser>` 类型，表示语法解析器。
  - **last_crossref_offset_**: 表示最后的交叉引用偏移量。
  - **status_**: 当前文档的可用状态。
  - **state_**: 用于跟踪当前的状态。
  - **offset_**: 当前的偏移量。
  - **cross_refs_for_check_**: 用于保存待检查的交叉引用偏移量的队列。
  - **registered_crossrefs_**: 保存已注册的交叉引用偏移量的集合。

这些接口与内部方法一起工作，以处理 PDF 文档的交叉引用表或流的可用性检查。这在处理损坏的或不完整的 PDF 文件时特别有用。
*/